package cn.jetpiece.cloud.joss.app.modular.object.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.jetpiece.cloud.joss.app.core.constant.OssConstants;
import cn.jetpiece.cloud.joss.app.modular.object.mapper.ProviderMapper;
import cn.jetpiece.cloud.joss.app.modular.object.service.BucketService;
import cn.jetpiece.cloud.joss.app.modular.object.service.ProviderService;
import cn.jetpiece.cloud.joss.app.modular.object.wrapper.ProviderWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.jetpiece.cloud.joss.api.object.model.params.CreateProviderParam;
import cn.jetpiece.cloud.joss.api.object.model.params.UpdateProviderParam;
import cn.jetpiece.cloud.joss.api.object.model.query.ProviderQuery;
import cn.jetpiece.cloud.joss.api.object.model.result.ProviderResult;
import cn.jetpiece.cloud.joss.app.modular.object.entity.Bucket;
import cn.jetpiece.cloud.joss.app.modular.object.entity.Provider;
import cn.jetpiece.cloud.joss.app.modular.object.enums.BasicExceptionEnum;
import cn.jetpiece.cloud.core.page.PageFactory;
import cn.jetpiece.cloud.model.exception.ServiceException;
import cn.jetpiece.cloud.model.page.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;

/**
 * <p>
 * 服务提供商 服务实现类
 * </p>
 *
 * @author XuJZ
 * @since 2020-09-05
 */
@Service
public class ProviderServiceImpl extends ServiceImpl<ProviderMapper, Provider> implements ProviderService {
    private RedisTemplate<String, Object> redisTemplate;
    private BucketService bucketService;

    @Autowired
    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Resource
    public void setBucketService(BucketService bucketService) {
        this.bucketService = bucketService;
    }

    @Override
    public boolean add(CreateProviderParam param) {
        Provider bean = new Provider();
        BeanUtil.copyProperties(param, bean);
        return super.save(bean);
    }

    @Override
    public boolean update(UpdateProviderParam param) {
        Provider oldBean = super.getById(param.getId());
        if (oldBean == null) {
            throw new ServiceException(BasicExceptionEnum.PROVIDER_NOT_EXISTED);
        }
        Provider update = BeanUtil.copyProperties(param, Provider.class);
        update.setId(param.getId());
        boolean result = super.updateById(update);
        if (result) {
            redisTemplate.boundHashOps(OssConstants.PROVIDER).delete(update.getId());
        }
        return result;
    }

    @Override
    public Provider getById(Serializable id) {
        if (ObjectUtil.isEmpty(id)) {
            return null;
        }
        Provider provider = (Provider) redisTemplate.boundHashOps(OssConstants.PROVIDER).get(id);
        if (provider == null) {
            provider = super.getById(id);
            if (provider == null) {
                return null;
            }
            redisTemplate.boundHashOps(OssConstants.PROVIDER).put(id, provider);
        }
        return provider;
    }

    @Override
    public boolean delete(String id) {
        Provider bean = super.getById(id);
        if (bean == null) {
            throw new ServiceException(BasicExceptionEnum.PROVIDER_NOT_EXISTED);
        }
        LambdaQueryWrapper<Bucket> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Bucket::getProviderId, id);
        if (bucketService.count(wrapper) > 0) {
            throw new ServiceException(BasicExceptionEnum.PROVIDER_CANNOT_DELETE_WITHOUT_NULL);
        }
        boolean result = super.removeById(id);
        if (result) {
            redisTemplate.boundHashOps(OssConstants.PROVIDER).delete(id);
        }
        return result;
    }

    @Override
    public PageResult<ProviderResult> page(ProviderQuery param) {
        LambdaQueryWrapper<Provider> wrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotEmpty(param.getId())) {
            wrapper.eq(Provider::getId, param.getId());
        }
        if (StrUtil.isNotEmpty(param.getProviderName())) {
            wrapper.eq(Provider::getProviderName, param.getProviderName());
        }
        if (param.getProviderType() != null) {
            wrapper.eq(Provider::getProviderType, param.getProviderType());
        }
        if (StrUtil.isNotEmpty(param.getAccessKey())) {
            wrapper.like(Provider::getAccessKey, param.getAccessKey());
        }
        if (param.getIsEnable() != null) {
            wrapper.eq(Provider::getIsEnable, param.getIsEnable());
        }
        IPage<Provider> iPage = PageFactory.defaultPage();
        IPage<Provider> page = super.page(iPage, wrapper);
        return new ProviderWrapper(page).setWrapper(param.getWrapper()).wrapPageResult();
    }
}
